package com.fp.m7.dao;

import java.util.List;

import javax.persistence.PersistenceException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.fp.m7.model.Account;
import com.fp.m7.repository.AccountRepository;
import com.google.common.collect.Lists;

@Transactional
public class AccountDaoImpl extends BaseDaoImpl<Account, AccountRepository>
		implements AccountDao {

	@Autowired
	private CommentDao commentDao;
	
	@Override
	public Account findByUsername(String username) {
		return repository.getByUsername(username);
	}

	@Override
	public Account findByNickname(String nickname) {
		return repository.getByNickname(nickname);
	}

	@Override
	public List<Account> findRandom(int count) {
		// TODO
		return Lists.newLinkedList();
	}

	@Override
	public Account persist(Account account) {
		validate(account);
		checkDuplicatesOnPersist(account);

		return super.persist(account);
	}

	private void checkDuplicatesOnPersist(Account account) {
		if (repository.getByUsername(account.getUsername()) != null) {
			throw new PersistenceException(String.format(
					"Username [%s] already taken.", account.getUsername()));
		}
		if (repository.getByNickname(account.getNickname()) != null) {
			throw new PersistenceException(String.format(
					"Nickname [%s] already taken.", account.getNickname()));
		}
	}

	@Override
	public Account merge(Account account) {
		checkDuplicatesOnMerge(account);
		return super.merge(account);
	}

	private void checkDuplicatesOnMerge(Account account) {
		Account found = repository.getByUsername(account.getUsername());
		if (found != null && !found.equals(account)) {
			throw new PersistenceException(String.format(
					"Username [%s] already taken.", account.getUsername()));
		}
		found = repository.getByNickname(account.getNickname());
		if (found != null && !found.equals(account)) {
			throw new PersistenceException(String.format(
					"Nickname [%s] already taken.", account.getNickname()));
		}
	}
	
	@Override
	public void remove(Account account) {
		commentDao.removeUsersComments(account);
		super.remove(account);
	}

}
